/**
 *
 * name: 倒计时 mixins
 * 
 * summary: 修复浏览器倒计时偏差问题
 * 
 *          需倒计时结束操作，请在组件methods中注册timeover回调函数
 *
 **/

export default {
    data() {
        return {
            //服务器时间, 在组件中重新赋值, 可接受字符串或时间戳格式的日期时间值
            currentTime: "2019-01-01",
            //倒计时结束时间, 在组件中重新赋值，可接受字符串或时间戳格式的日期时间值
            startTime: "2019-01-01",
            //倒计时实时结果对象, 在组件中watch进行业务处理、个性化样式
            countdownTime: {},
            //倒计时对象
            _timeCounter: null
        };
    },
    computed: {
        _offset: function() {
            return this._end - this._now;
        },
        _end: function() {
            if (typeof this.startTime === "string") {
                return new Date(
                    Date.parse(this.startTime.replace(/-/g, "/"))
                ).getTime();
            } else if (typeof this.startTime === "number") {
                return new Date(this.startTime).getTime();
            }
        },
        _now: function() {
            if (typeof this.currentTime === "string") {
                return new Date(
                    Date.parse(this.currentTime.replace(/-/g, "/"))
                ).getTime();
            } else if (typeof this.currentTime === "number") {
                return new Date(this.currentTime).getTime();
            }
        }
    },
    watch: {
        _offset: {
            handler: function(vel) {
                vel > 0 && this._down(vel);
            },
            immediate: true
        }
    },
    destroyed() {
        clearTimeout(this._timeCounter);
        this._timeCounter = null;
    },
    methods: {
        filt(val) {
            return val > 9 ? val : "0" + val;
        },
        _timeCallback(offset) {
            let data = {
                dd: this.filt(Math.floor(offset / 1000 / 60 / 60 / 24)),
                hh: this.filt(Math.floor((offset / 1000 / 60 / 60) % 24)),
                mm: this.filt(Math.floor((offset / 1000 / 60) % 60)),
                ss: this.filt(Math.floor((offset / 1000) % 60))
            };
            this.countdownTime = data;

            // console.log(
            //     "--------------------",
            //     JSON.stringify(this.countdownTime)
            // );
        },
        _down(val) {
            const interval = 1000; //每次间隔ms数
            let ms = val; // 从服务器和活动开始时间计算出的时间差，这里测试用 50000 ms
            let count = 0; //倒计时次数
            const startTime = new Date().getTime(); //此值用于矫正偏差用

            const countDownStart = callback => {
                count++;
                const offset =
                    new Date().getTime() - (startTime + count * interval); // A
                let nextTime = interval - offset;
                if (nextTime < 0) {
                    nextTime = 0;
                }
                ms -= interval;
                //console.log(`误差：${offset} ms`);

                //倒计时终止
                if (ms < 0) {
                    clearTimeout(this._timeCounter);
                    if (typeof this.timeover === "function") {
                        this.timeover();
                    }
                } else {
                    callback && callback(ms);
                    this._timeCounter = setTimeout(() => {
                        countDownStart(callback);
                    }, nextTime);
                }
            };

            if (ms >= 0) {
                this._timeCounter = setTimeout(() => {
                    countDownStart(this._timeCallback);
                }, interval);
            }
        }
    }
};
